package instructions;

import expressions.BadExpressionException;
import expressions.Expression;
import values.Value;
import base.AST;
import base.Environment;
import base.Interpreter;

public class Print implements Instruction {

	private AST son;

	/**
	 * Creates the instruction
	 * print(son)
	 */
	public Print(AST son) {
		assert son instanceof Value || son instanceof Expression;

		this.son = son;
	}

	/**
	 * Prints the value of son in the standard output
	 */
	public Environment instr(Environment env) throws BadInstructionException {

		Value toPrint;

		try {
			toPrint = Interpreter.getBoolean(this.son, env);
		} catch (BadExpressionException e1) {
			try {
				toPrint = Interpreter.getInt(this.son, env);
			} catch (BadExpressionException e2) {
				try {
					toPrint = Interpreter.getArray(this.son, env);
				} catch (BadExpressionException e3) {
					try {
						toPrint = Interpreter.getString(this.son, env);
					} catch (BadExpressionException e4) {
						throw new BadInstructionException(
								"Trying to print a non-boolean, non-integer, non-array or non-string");
					}
				}
			}
		}

		System.out.println(toPrint);

		return env;
	}

}
